package com.ruoyi.project.order.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.common.constant.OrderStatu;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.utils.security.ShiroUtils;
import com.ruoyi.framework.aspectj.lang.annotation.Log;
import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.framework.web.page.TableDataInfo;
import com.ruoyi.project.order.domain.Customer;
import com.ruoyi.project.order.domain.OrderFankui;
import com.ruoyi.project.order.domain.OrderType;
import com.ruoyi.project.order.domain.WorkOrder;
import com.ruoyi.project.order.mapper.WorkOrderMapper;
import com.ruoyi.project.order.service.ICustomerService;
import com.ruoyi.project.order.service.IOrderFankuiService;
import com.ruoyi.project.order.service.IOrderTypeService;
import com.ruoyi.project.order.service.IWorkOrderService;
import com.ruoyi.project.order.vo.OrderFanKuiVo;
import com.ruoyi.project.order.vo.OrderListVo;
import com.ruoyi.project.order.vo.SelectOrderVo;
import com.ruoyi.project.order.wx.TemplateId;
import com.ruoyi.project.order.wx.WxSender;
import com.ruoyi.project.system.user.domain.User;
import com.ruoyi.project.system.user.domain.UserRole;
import com.ruoyi.project.system.user.mapper.UserMapper;
import com.ruoyi.project.system.user.mapper.UserRoleMapper;
import com.ruoyi.project.system.user.service.IUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.Size;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;


@RequestMapping("/order")
@Slf4j
@Controller
public class OrderController extends BaseController {
    @Autowired
    UserMapper userMapper;

    @Autowired
    UserRoleMapper userRoleMapper;
    @Autowired
    ICustomerService iCustomerService;
    @Autowired
    IWorkOrderService iWorkOrderService;
    @Autowired
    IOrderTypeService iOrderTypeService;
    @Autowired
    IUserService iUserService;
    @Autowired
    WorkOrderMapper workOrderMapper;
    @Autowired
    IOrderFankuiService iOrderFankuiService;

    /**
     * 系统说明
     */
    @RequestMapping("system_info")
    public String sysInfo() {

        return "order/system_info";
    }

    /**
     * 去发布订单页面
     *
     * @param model
     * @param tip
     * @return
     */
    @RequestMapping("/to_order_issue")
    public String toOrderIssue(Model model, String tip) {
        log.info("进入订单发布页面");
        //返回接单人
        //查询所有userId
        List<UserRole> userRoles = userRoleMapper.selectUserIdByUserRole(3L);
        //查询所有user
        List<User> worker = new ArrayList<>();
        for (UserRole userRole : userRoles) {
            User user = userMapper.selectUserById(userRole.getUserId());
            worker.add(user);
        }
        model.addAttribute("workers", worker);
        model.addAttribute("tip", tip);
        //返回类型
        model.addAttribute("types", iOrderTypeService.list());
        model.addAttribute("customers", iCustomerService.list());

        return "order/order_issue";
    }


    /**
     * 工单发布
     *
     * @param order
     * @param customer
     * @param type
     * @return
     */
    @RequestMapping("/order_issue")
    public String orderIssue(WorkOrder order, Customer customer, String type) {
        log.info("开始发布订单--------------------------");
        log.info(order.toString());
        log.info(customer.toString());
        log.info(type);
        //查询类型是否存在
        type = type.trim();
        OrderType rOrderType = iOrderTypeService.getOne(new QueryWrapper<OrderType>().lambda().eq(OrderType::getTypeName, type));
        if (rOrderType == null) {
            rOrderType = new OrderType();
            rOrderType.setTypeName(type);
            iOrderTypeService.save(rOrderType);
            log.info("添加type: " + rOrderType);
        }
        //查询客户是否存在
        Customer rCustomer = iCustomerService.getOne(new QueryWrapper<Customer>().lambda()
                .eq(Customer::getCustomerName, customer.getCustomerName().trim())
                .eq(Customer::getCustomerPhone, customer.getCustomerPhone().trim())
                .eq(Customer::getCustomerAddress, customer.getCustomerAddress().trim())
        );
        if (rCustomer == null) {
            rCustomer = customer;
            iCustomerService.save(rCustomer);
            log.info("添加客户: " + rCustomer);
        }
        //添加订单4
        order.setPublisherId(ShiroUtils.getSysUser().getUserId().intValue());
        order.setCustomerId(rCustomer.getId());
        order.setOrderCreateTime(LocalDateTime.now());
        order.setOrderType(rOrderType.getId());
        order.setOrderStatus(OrderStatu.DaiQueRen.getValue());
        iWorkOrderService.save(order);
        log.info("订单发布完成--------------------------");
        //提醒工人接单
        if (null != order.getWorkerId()) {
            WxSender.sendMsg(order.getWorkerId(), TemplateId.newWorkOrderTip, "你有一条新的工单,请尽快确认", order.getOrderTitle(), order.getOrderId(), "请到系统查看", getSysUser().getUserName(), getSysUser().getPhonenumber(), "客户信息: \n" + customer.getCustomerName() + "\n" + customer.getCustomerPhone() + "\n" + customer.getCustomerAddress());
        } else {
            //提醒所有接单员
            List<UserRole> userRoles = userRoleMapper.selectUserIdByUserRole(3L);
            //查询所有user
            for (UserRole userRole : userRoles) {
                User user = userMapper.selectUserById(userRole.getUserId());
                WxSender.sendMsg(user.getUserId().intValue(), TemplateId.newWorkOrderTip, "有新的工单发布,您可以去接单啦~", order.getOrderTitle(), order.getOrderId(), "请到系统查看", getSysUser().getUserName(), getSysUser().getPhonenumber(), "客户信息: \n" + customer.getCustomerName() + "\n" + customer.getCustomerPhone() + "\n" + customer.getCustomerAddress());
            }
        }

        return HttpUtil.encodeParams("redirect:to_order_issue?tip=发布成功", CharsetUtil.CHARSET_UTF_8);
    }

    /**
     * 工单详情
     *
     * @param operId
     * @param mmap
     * @return
     */
    @GetMapping("/detail/{operId}")
    public String detail(@PathVariable("operId") Integer operId, ModelMap mmap) {
        SelectOrderVo selectOrderVo = new SelectOrderVo();
        selectOrderVo.setOrderId(operId);
        //查找评论
        List<OrderFanKuiVo> orderFanKuiVos = workOrderMapper.LGetFanKui(operId);
        mmap.put("orderListVo", workOrderMapper.LGetList(selectOrderVo).get(0));
        mmap.put("fanKui", orderFanKuiVos);

        return "order/order_info";
    }

    /**
     * 去报价
     *
     * @return
     */
    @GetMapping("/money/{id}")
    public String toMoney(@PathVariable("id") Integer id, Model model) {
        log.info("报价订单:" + id);
        model.addAttribute("id", id);
        System.out.println("回复: " + id);
        return "order/orderMoney";
    }


    /**
     * 确认工单
     */
    @RequiresPermissions("order:queren")
    @GetMapping("/confirm/{id}")
    @ResponseBody
    public AjaxResult confirm(@PathVariable("id") Integer Id) {
        WorkOrder rWorkOrder = iWorkOrderService.getById(Id);
        if (rWorkOrder.getOrderStatus() == OrderStatu.DaiQueRen.getValue()) {
            //如果是待确认状态, 确认订单
            rWorkOrder.setOrderStatus(OrderStatu.ChuLiZhong.getValue());
            iWorkOrderService.updateById(rWorkOrder);
            WxSender.sendMsg(rWorkOrder.getPublisherId(), TemplateId.WorkOrderQueRen, "你的工单(" + rWorkOrder.getOrderTitle() + ")已被确认", rWorkOrder.getOrderId(), getSysUser().getUserName() + "已确认", "");
            return AjaxResult.success("确认订单成功,请尽快处理");
        }
        return AjaxResult.error("该订单当前状态为: " + OrderStatu.getByValue(rWorkOrder.getOrderStatus()).getName() + ",无法确认");
    }

    /**
     * 关闭工单
     */
    @RequiresPermissions("order:close")
    @GetMapping("/close/{id}")
    @ResponseBody
    public AjaxResult close(@PathVariable("id") Integer Id) {
        WorkOrder rWorkOrder = iWorkOrderService.getById(Id);
        if (rWorkOrder.getOrderStatus() <= OrderStatu.ChuLiZhong.getValue()) {
            //关闭订单
            rWorkOrder.setOrderStatus(OrderStatu.YiGuanBi.getValue());
            iWorkOrderService.updateById(rWorkOrder);
            //通知
            WxSender.sendMsg(rWorkOrder.getWorkerId(), TemplateId.WorkOrderClose, "你的工单" + rWorkOrder.getOrderId() + "已被关闭", rWorkOrder.getOrderTitle(), getSysUser().getUserName(), DateUtil.now(), "请详询取消人员", "");
            return AjaxResult.success("工单关闭成功");
        }
        return AjaxResult.error("该订单当前状态为: " + OrderStatu.getByValue(rWorkOrder.getOrderStatus()).getName() + ",无法关闭");
    }

    /**
     * 完成工单
     */
    @RequiresPermissions("order:queren")
    @RequestMapping("/finish")
    @ResponseBody
    public AjaxResult finish(Integer id, WorkOrder workOrder) {
        WorkOrder rWorkOrder = iWorkOrderService.getById(id);
        if (rWorkOrder.getOrderStatus() == OrderStatu.ChuLiZhong.getValue()) {
            //完成订单
            rWorkOrder.setOrderStatus(OrderStatu.YiWanCheng.getValue());
            //加入完成时间
            rWorkOrder.setOrderFinishTime(LocalDateTime.now());
            //加入金额
            rWorkOrder.setOrderCarMoney(workOrder.getOrderCarMoney());
            rWorkOrder.setOrderPostMoney(workOrder.getOrderPostMoney());
            rWorkOrder.setOrderOtherMoney(workOrder.getOrderOtherMoney());
            iWorkOrderService.updateById(rWorkOrder);
            //通知
            WxSender.sendMsg(rWorkOrder.getPublisherId(), TemplateId.WorkOrderFinish, "您的工单 " + rWorkOrder.getOrderTitle() + " 已完成", rWorkOrder.getOrderId(), DateUtil.formatLocalDateTime(rWorkOrder.getOrderCreateTime()), DateUtil.now(), "完成人: " + getSysUser().getUserName());
            return AjaxResult.success("任务已完成,并提交审核");
        }
        return AjaxResult.error("该订单当前状态为: " + OrderStatu.getByValue(rWorkOrder.getOrderStatus()).getName() + ",无法完成任务");
    }

    /**
     * 完成工单
     */
    @RequiresPermissions("order:queren")
    @RequestMapping("jieDan/{id}")
    @ResponseBody
    public AjaxResult jiedan(@PathVariable Integer id) {
        WorkOrder rWorkOrder = iWorkOrderService.getById(id);
        if (rWorkOrder.getOrderStatus() == OrderStatu.DaiQueRen.getValue()) {
            rWorkOrder.setWorkerId(getUserId().intValue());
            rWorkOrder.setOrderStartTime(LocalDateTime.now());
            rWorkOrder.setOrderStatus(OrderStatu.ChuLiZhong.getValue());
            workOrderMapper.updateById(rWorkOrder);
            WxSender.sendMsg(rWorkOrder.getPublisherId(), TemplateId.WorkOrderQueRen, "你的工单(" + rWorkOrder.getOrderTitle() + ")已被接单", rWorkOrder.getOrderId(), getSysUser().getUserName() + "已确认", "");
            return AjaxResult.success("您已经成功接受此工单,请尽快完成哦");
        }
        return AjaxResult.error("该订单当前状态为: " + OrderStatu.getByValue(rWorkOrder.getOrderStatus()).getName() + ",无法接受任务");
    }


    /**
     * 去修改工单
     */
    @GetMapping("/edit/{id}")
    public String edit(@PathVariable("id") Integer Id, String tip, Model model) {
        SelectOrderVo selectOrderVo = new SelectOrderVo();
        selectOrderVo.setOrderId(Id);
        //查询所有userId
        List<UserRole> userRoles = userRoleMapper.selectUserIdByUserRole(3L);
        //查询所有user
        List<User> worker = new ArrayList<>();
        for (UserRole userRole : userRoles) {
            User user = userMapper.selectUserById(userRole.getUserId());
            worker.add(user);
        }
        model.addAttribute("workers", worker);
        //返回类型
        model.addAttribute("types", iOrderTypeService.list());
        model.addAttribute("tip", tip);
        model.addAttribute("customers", iCustomerService.list());
        model.addAttribute("orderListVo", workOrderMapper.LGetList(selectOrderVo).get(0));
        return "order/order_edit";
    }


    /**
     * 工单修改
     *
     * @param order
     * @param customer
     * @param type
     * @return
     */
    @RequiresPermissions("order:edit")
    @RequestMapping("/order_edit")
    public String order_edit(WorkOrder order, Customer customer, String type, Model model) {
        log.info("开始修改订单--------------------------" + order.getOrderId());
        //先把原先订单关闭
        WorkOrder rWorkerOrder = iWorkOrderService.getById(order.getOrderId());
        if (rWorkerOrder.getOrderStatus() > OrderStatu.ChuLiZhong.getValue()) {
            //如果已经是完成状态. 不可修改
            model.addAttribute("msg", "修改失败!本订单状态:  " + OrderStatu.getByValue(rWorkerOrder.getOrderStatus()).getName() + ",不可以再次修改);");
            return "msg/error";
        }
        rWorkerOrder.setOrderStatus(OrderStatu.YiGuanBi.getValue());
        iWorkOrderService.updateById(rWorkerOrder);
        //重新发布
        order.setOrderId(null);
        log.info(order.toString());
        log.info(customer.toString());
        log.info(type);
        //查询类型是否存在
        type = type.trim();
        OrderType rOrderType = iOrderTypeService.getOne(new QueryWrapper<OrderType>().lambda().eq(OrderType::getTypeName, type));
        if (rOrderType == null) {
            rOrderType = new OrderType();
            rOrderType.setTypeName(type);
            iOrderTypeService.save(rOrderType);
            log.info("添加type: " + rOrderType);
        }
        //查询客户是否存在
        Customer rCustomer = iCustomerService.getOne(new QueryWrapper<Customer>().lambda()
                .eq(Customer::getCustomerName, customer.getCustomerName().trim())
                .eq(Customer::getCustomerPhone, customer.getCustomerPhone().trim())
                .eq(Customer::getCustomerAddress, customer.getCustomerAddress().trim())
        );
        if (rCustomer == null) {
            rCustomer = customer;
            iCustomerService.save(rCustomer);
            log.info("添加客户: " + rCustomer);
        }
        //添加订单4
        order.setPublisherId(ShiroUtils.getSysUser().getUserId().intValue());
        order.setCustomerId(rCustomer.getId());
        order.setOrderCreateTime(LocalDateTime.now());
        order.setOrderType(rOrderType.getId());
        order.setOrderStatus(OrderStatu.DaiQueRen.getValue());
        iWorkOrderService.save(order);
        log.info("订单修改完成--------------------------");
        //通知被关闭的
        WxSender.sendMsg(rWorkerOrder.getWorkerId(), TemplateId.WorkOrderClose, "你的工单" + rWorkerOrder.getOrderId() + "已被关闭", rWorkerOrder.getOrderTitle(), getSysUser().getUserName(), DateUtil.now(), "请详询取消人员", "");
        //通知新接收的
        WxSender.sendMsg(order.getWorkerId(), TemplateId.newWorkOrderTip, "订单已关闭并重新发给了你", order.getOrderTitle(), order.getOrderId(), "请到系统查看", getSysUser().getUserName(), getSysUser().getPhonenumber(), "客户信息: \n" + customer.getCustomerName() + "\n" + customer.getCustomerPhone() + "\n" + customer.getCustomerAddress());

        model.addAttribute("msg", "修改完成 ,本订单已关闭并重新发布 ! 请到列表页刷新查看");
        return "msg/success";
    }


    @GetMapping("type")
    public String type(Model model) {
        List<OrderType> list = iOrderTypeService.list();
        model.addAttribute("types", list);
        return "order/order_type";
    }

    @GetMapping("/{id}")
    public String to(@PathVariable(value = "id") Integer id) {

        return "order/order_" + id;
    }

    @Log(title = "工单", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    @ResponseBody
    public AjaxResult export(SelectOrderVo selectOrderVo) {
        log.info("导出");
        log.info(selectOrderVo.toString());
        List<OrderListVo> orderListVos = workOrderMapper.LGetList(selectOrderVo);
        ExcelUtil<OrderListVo> util = new ExcelUtil<OrderListVo>(OrderListVo.class);
        //如果有检测逾期
        if (StrUtil.isNotBlank(selectOrderVo.getTimeOut())) {
            List<OrderListVo> yqOrderList = new ArrayList<>();
            for (OrderListVo orderListVo : orderListVos) {
                if (orderListVo.getOrderFinishTime() != null) {
                    if (DateUtil.parseLocalDateTime(orderListVo.getOrderFinishTime()).isAfter(DateUtil.parseLocalDateTime(orderListVo.getOrderEndTime()))) {
                        yqOrderList.add(orderListVo);
                    }
                } else {
                    if (DateUtil.parseLocalDateTime(orderListVo.getOrderEndTime()).isBefore(LocalDateTime.now())) {
                        yqOrderList.add(orderListVo);
                    }
                }
            }
            return util.exportExcel(yqOrderList, "工单数据");
        }
        return util.exportExcel(orderListVos, "工单数据");
    }

    @RequestMapping("list/{id}")
    @ResponseBody
    public TableDataInfo list(@PathVariable(value = "id") Integer id, SelectOrderVo selectOrderVo) {
        startPage();
        List<OrderListVo> orderListVos = null;
        switch (id) {
            case 1:
                selectOrderVo.setOrderStatu(OrderStatu.DaiQueRen.getValue());
                break;
            case 2:
                selectOrderVo.setOrderStatu(OrderStatu.ChuLiZhong.getValue());
                break;
            case 3:
                selectOrderVo.setOrderStatu(OrderStatu.YiWanCheng.getValue());
                break;
        }
        //如果有检测逾期
        if (StrUtil.isNotBlank(selectOrderVo.getTimeOut())) {
            orderListVos = workOrderMapper.LGetListNoContentAndYuQi(selectOrderVo);
        } else {
            if (id == 4) {
                orderListVos = workOrderMapper.LGetListJieDan(new SelectOrderVo());
            } else {
                orderListVos = workOrderMapper.LGetListNoContent(selectOrderVo);
            }
        }

        return getDataTable(orderListVos);
    }


    @GetMapping("/tofankui/{operId}")
    public String tofankui(@PathVariable("operId") Integer operId, ModelMap mmap) {
        SelectOrderVo selectOrderVo = new SelectOrderVo();
        selectOrderVo.setOrderId(operId);
        //查找评论
        mmap.put("orderListVo", workOrderMapper.LGetList(selectOrderVo).get(0));

        return "order/order_fankui";
    }


    @RequestMapping("order_fankui")
    public String orderFankui(Integer orderId, String msg, Model model) {
        OrderFankui orderFankui = new OrderFankui();
        orderFankui.setMsg(msg);
        orderFankui.setOrderId(orderId);
        orderFankui.setMsgTime(LocalDateTime.now());
        orderFankui.setUserId(getUserId().intValue());
        iOrderFankuiService.save(orderFankui);
        //通知
        WorkOrder order = iWorkOrderService.getById(orderId);
        if (getUserId().intValue() == order.getWorkerId()) {
            //如果是工人发布的
            //通知发布者
            WxSender.sendMsg(order.getPublisherId(), TemplateId.WorkOrderFanKui, "您的工单有新的反馈", order.getOrderTitle(), getSysUser().getUserName(), DateUtil.now(), msg.length() > 25 ? "内容过长,请到系统查看" : msg, "工单id: " + order.getOrderId());
        } else if (getUserId().intValue() == order.getPublisherId()) {
            //如果是发布者发布的
            //通知工人
            WxSender.sendMsg(order.getWorkerId(), TemplateId.WorkOrderFanKui, "您的工单有新的反馈", order.getOrderTitle(), getSysUser().getUserName(), DateUtil.now(), msg.length() > 25 ? "内容过长,请到系统查看" : msg, "工单id: " + order.getOrderId());
        } else {
            //通知工人和发布者
            WxSender.sendMsg(order.getPublisherId(), TemplateId.WorkOrderFanKui, "您的工单有新的反馈", order.getOrderTitle(), getSysUser().getUserName(), DateUtil.now(), msg.length() > 25 ? "内容过长,请到系统查看" : msg, "工单id: " + order.getOrderId());
            WxSender.sendMsg(order.getWorkerId(), TemplateId.WorkOrderFanKui, "您的工单有新的反馈", order.getOrderTitle(), getSysUser().getUserName(), DateUtil.now(), msg.length() > 25 ? "内容过长,请到系统查看" : msg, "工单id: " + order.getOrderId());
        }

//        return "redirect:/order/detail/" + orderId;
        model.addAttribute("msg", "订单反馈完成");
        return "msg/success";
    }

    /**
     * 催单
     */
    @RequestMapping("cui/{id}")
    @ResponseBody
    public AjaxResult cui(@PathVariable("id") Integer orderId) {

        //通知工人
        WorkOrder order = iWorkOrderService.getById(orderId);
        //如果完成,不提醒
        if (order.getOrderStatus() >= OrderStatu.YiWanCheng.getValue()) {
            return AjaxResult.error("此工单已经完成了,不可以催单");
        }

        WxSender.sendMsg(order.getWorkerId(), TemplateId.WorkOrderCui, "请尽快完成工单: "
                + order.getOrderTitle(), getSysUser().getUserName(), "请尽快完成任务!", "工单id: " + order.getOrderId());
        return AjaxResult.success("催单成功");
    }
}
